/*---------------------------------------------------------------
    File: wf_string_util.cpp
  
    Description: String utilities

    Author:                                              
        Walter Fan    (walterfan@qq.com)                
                                                      
    History:                                             
        1/25/2010  Create                                

----------------------------------------------------------------*/ 
#include <stdio.h>
#include <string.h>
#include <stdarg.h>
#include <exception>
#include "wf_string_util.h"
using namespace std;

int safe_snprintf(LPSTR s, size_t n, LPCSTR format, ...)
{
    va_list ap;
    va_start(ap, format);
    size_t ret = vsnprintf(s, n, format, ap);
    va_end(ap);
       
    // If returned size is over actual buffer size, 
    // we should use strlen(x) to get the actual formated buf size
    if( (ret + 1) > n )
        return strlen(s);
    
    return ret;
}

LPSTR safe_strdup(LPCSTR s)
{
    if(!s)
        return NULL;
        
    LPSTR pDest = new char[strlen(s) + 1];
    if(pDest)
        strcpy(pDest, s);
            
    return pDest;
}

void safe_strcpy(LPSTR pDest, LPSTR pSrc, int nCount)
{
    if(!pSrc || !pDest) 
        return;
    int nLen = (int)strlen(pSrc)+1;
    if(nLen > nCount)
        nLen = nCount;
    memcpy(pDest, pSrc, nLen);
    *(pDest + nLen -1) = '\0';
    return;
}

LPSTR to_upper(LPSTR s)
{
    if(!s)
        return s;
    
    LPSTR p = s;
    while ( *p != '\0' )
    {
        *p = toupper(*p);
        ++ p;
    }
    return s;
}

LPSTR to_lower(LPSTR s)
{
    if(!s)
        return s;
    
    LPSTR p = s;
    while ( *p != '\0' )
    {
        *p = tolower(*p);
        ++ p;
    }
    return s;
}

string UpperCase( const string& p_string )
{
    string str = p_string;

    for( size_t i = 0; i < str.size(); i++ )
    {
        str[i] = toupper( str[i] );
    }
    return str;
}

string LowerCase( const string& p_string )
{
    string str = p_string;

    for( size_t i = 0; i < str.size(); i++ )
    {
        str[i] = tolower( str[i] );
    }
    return str;
}

string SearchAndReplace(
    const string& p_target,
    const string& p_search,
    const string& p_replace )
{
    string str( p_target );
    string::size_type i = str.find( p_search );
    
    // loop while replacing all occurances
    while( i != string::npos )
    {
        str.replace( i, p_search.size(), p_replace );
        i = str.find( p_search, i + 1 );
    }

    return str;
}



string Trim( const string& p_string )
{
    int wsf;
    int wsb;

    // trim the front
    wsf = p_string.find_first_not_of( WHITESPACE );
    wsb = p_string.find_last_not_of( WHITESPACE );

    if( (size_t)wsf == string::npos )
    {
        wsf = 0;
        wsb = -1;
    }

    return p_string.substr( wsf, wsb - wsf + 1 );
}

string RTrim(const string& s,u_int len)
{
	if(s.length()<=len)
	{
		return s;
	}
	else
	{
		string shortstr=string(s, 0, len);
		shortstr=shortstr+"...";
		return shortstr;
	}
}

string ParseWord( const string& p_string, int p_index )
{
    int wss = p_string.find_first_not_of( WHITESPACE );

    while( p_index > 0 )
    {
        p_index--;

        // find the beginning of the next word, by finding whitespace
        // to end the current word, and then non-whitespace at the start
        // of the next word
        wss = p_string.find_first_of( WHITESPACE, wss );
        wss = p_string.find_first_not_of( WHITESPACE, wss );
    }

    // find the end of the word
    int wse = p_string.find_first_of( WHITESPACE, wss );

    if( (size_t)wss == string::npos )
    {
        wss = 0;
        wse = 0;
    }

    return p_string.substr( wss, wse - wss );
}

string RemoveWord( const string& p_string, int p_index )
{
    int wss = p_string.find_first_not_of( WHITESPACE );

    while( p_index > 0 )
    {
        p_index--;

        // find the beginning of the next word, by finding whitespace
        // to end the current word, and then non-whitespace at the start
        // of the next word
        wss = p_string.find_first_of( WHITESPACE, wss );
        wss = p_string.find_first_not_of( WHITESPACE, wss );
    }

    // find the end of the word
    int wse = p_string.find_first_of( WHITESPACE, wss );

    // find the beginning of the next word
    wse = p_string.find_first_not_of( WHITESPACE, wse );

    if( (size_t)wss == string::npos )
    {
        wss = 0;
        wse = 0;
    }

    string str = p_string;
    str.erase( wss, wse - wss );
    return str;
}
